#include "gameframework.h"
#include "ui_gameframework.h"
#include<math.h>
#include<algorithm>
gameframework::gameframework(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::gameframework)
{
    ui->setupUi(this);
    this->setFixedSize(1800,1300);
    

    //升级子弹和射手的按钮
    label_shoot_update=new QLabel(this);
    label_shoot_update->setText("按1射手升级:"+QString::number(update_shoot1)+"阳光");
    QFont font("微软雅黑",12);
    label_shoot_update->setFont(font);
    label_shoot_update->setGeometry(0,0,250,50);
    label_shoot_update->setStyleSheet("color:red;background-color:yellow");
    label_bullet_update=new QLabel(this);
    label_bullet_update->setText("按2子弹升级:"+QString::number(update_bullet1)+"阳光");
    label_bullet_update->setFont(font);
    label_bullet_update->setGeometry(0,50,250,50);
    label_bullet_update->setStyleSheet("color:red;background-color:blue");
    timer_update=new QTimer(this);
    timer_update->start(update_fre);
    connect(timer_update,&QTimer::timeout,this,[=](){
        update();
    });

    label_sunnum=new QLabel(this);
    label_sunnum->setText(QString::number(sum_sunnum));
    label_sunnum->setFont(font);
    label_sunnum->setStyleSheet("color:red");
    label_sunnum->setGeometry(530,65,100,100);
}

gameframework::~gameframework()
{
    delete ui;
}

void gameframework::Paint(QPainter *pa, QPixmap &pm, QString str, int x, int y, int w, int h)
{
    pm.load(str);
    pa->drawPixmap(x,y,w,h,pm);
}

void gameframework::InitElement()
{

    plants.resize(5);
    zoms.resize(5);
    for(int i=0;i<5;i++)
        plants[i].resize(9);
}

void gameframework::InitGraph(QPainter *pa, QPixmap &pm)
{
    Paint(pa,pm,":/background/moring.jpg",0,0,1800,1300);
    Paint(pa,pm,":/background/bar4.png",500,0,700,140);
    Paint(pa,pm,":/card/card_4.png",600,0,70,125);
    Paint(pa,pm,":/card/card_iceshroom.png",670,0,70,125);
    Paint(pa,pm,":/card/card_wallnut.png",740,0,70,125);
    
    
    //更新射手
    QString str;
    if(shoot_level==2)
        str=":/shootplant/double.png";
    else if(shoot_level==3)
        str=":/shootplant/jiqiang.png";
    else
        str=":/shootplant/single.png";
    Paint(pa,pm,str,330+col*105+4,170+210*row+60,100,100);
    
}

void gameframework::ObserveBullet(QPainter *pa, QPixmap &pm)
{
    
    auto it=bullets.begin();
    while(it!=bullets.end())
    {
        int& x=(*it).x;
        int y=(*it).y;
        int attack=(*it).attack;
        int type=(*it).type;
        int reduce_speed=1;
        int fly_speed=(*it).speed;
        int row=(y-170)/210;
        QString str;
        if(type==1)
            str=":/bullettype/pea.png";
        else if(type==2)
        {
            str=":/bullettype/snowpea.png";
            reduce_speed=2;
        }
        else if(type==3)
        {
            str=":/bullettype/firepea.png";
            reduce_speed=2;
            attack*=2;
        }
        Paint(pa,pm,str,x,y,70,50);
        bool exist=true;
        if(zoms[row].size())
        {
            if(abs(zoms[row][0].x-x)<=25)
            {
                zoms[row][0].life-=attack;
                if(reduce_speed==2)
                {
                    zoms[row][0].reduce_statue=true;
                    zoms[row][0].reduce_time=4000;
                }
                exist=false;
            }
        }
        else
        {
            if(x>=1300)
                exist=false;
        }
        if(exist==false)
            it=bullets.erase(it);
        else
        {
            x+=fly_speed;
            ++it;
        }
        
    }
    
}

void gameframework::MakeBullet()
{
    if(fire_statue)
    {
        if(fire_pre>=fire_fre)
        {
            fire_pre=0;
            bullet_num--;
            //produce bullet
            bullets.push_back(bullet(bullet_attack,330+col*105+4+10,170+210*row+60,bullet_type,bullet_speed));
        }
        else {
            fire_pre+=update_fre;
        }
        if(bullet_num==0)
            fire_statue=false;
    }
    else
    {
        if(bullet_pre>=bullet_fre)
        {
            bullet_pre=0;
            fire_statue=true;
            if(shoot_level==1)
                bullet_num=1;
            else if(shoot_level==2)
                bullet_num=2;
            else if(shoot_level==3)
                bullet_num=4;
        }
        else
            bullet_pre+=update_fre;
    }
}

void gameframework::MakeZom()
{
    if(zom_pre>=zom_fre)
    {
        zom_pre=0;
        int z1;
        int z2;
        int z3;
        int z4;
        int z5;
        int type;
        int x=rand()%1000;
        int r=rand()%5;
        int y=170+r*210;
        int life;
        int walk_speed=5;
        if(stage==1)
        {
            z1=500;z2=800;
            z3=900;
            z4=1000;
        }
        else if(stage==2)
        {
            z1=300;
            z2=500;
            z3=700;
            z4=900;
            z5=1000;
        }
        else if(stage==3)
        {
            z1=100;
            z2=200;
            z3=400;
            z4=600;
            z5=1000;
        }
        if(x<=z1)
        {
            life=1000;
            type=0;
        }
        else if(x<=z2)
        {
            life=1500;
            type=1;
        }
        else if(x<=z3)
        {
            life=3000;
            type=2;
        }
        else if(x<=z4)
        {
            life=4000;
            type=3;
        }
        else if(x<=z5)
        {
            life=6000;
            walk_speed=10;
            type=4;
        }
        zom z(1300,y,life+add_life,type,walk_speed);
        zoms[r].push_back(z);
    }
    else
        zom_pre+=update_fre;
}

void gameframework::ObserveZom(QPainter *pa, QPixmap &pm)
{
    for(int i=0;i<zoms.size();i++)
    {
        auto it=zoms[i].begin();
        while(it!=zoms[i].end())
        {
            int life=(*it).life;
            int &x=(*it).x;
            int y=170+i*210;
            int& walk_speed=(*it).walk_speed;
            int walk_speed_normal=(*it).walk_speed_normal;
            int walk_speed_reduce=(*it).walk_speed_reduce;
            int eat_fre=(*it).eat_fre;
            int& eat_pre=(*it).eat_pre;
            int type=(*it).type;
            int attack=(*it).attack;
            bool& freeze_statue=(*it).freeze_statue;
            bool& reduce_statue=(*it).reduce_statue;
            int& freeze_time=(*it).freeze_time;
            int& reduce_time=(*it).reduce_time;
            QString str;
            //渲染僵尸
            if(type==0)
            {
                str=":/zomtype/common.png";
            }
            else if(type==1)
            {
                str=":/zomtype/luzhang.png";
            }
            else if(type==2)
            {
                str=":/zomtype/tiemen.png";
            }
            else if(type==3)
            {
                str=":/zomtype/tietong.png";
            }
            else if(type==4)
            {
                str=":/zomtype/ganlanqiu.png";
            }
            Paint(pa,pm,str,x,y,200,200);
            if(life<=0)
            {
                it=zoms[i].erase(it);
                int prob=rand()%10;
                if(prob<=7 )
                {
                    collect_sun.push_back(sunshine(x,y));
                }
            }
            else
            {
                float init_l=(*it).init_life+0.00;
                float l=(*it).life+0.00;
                float rate=l/init_l;
                pa->drawLine(x+80,y,x+80+80*rate,y);
                ++it;
                //僵尸被冰冻逻辑
                if(freeze_statue)
                {
                    freeze_time-=update_fre;
                    Paint(pa,pm,":/assitant/icetrap.png",x+100,y+140,60,60);
                    if(freeze_time<=0)
                    {
                        freeze_statue=false;
                        reduce_statue=true;
                        reduce_time=4000;
                    }
                    continue;
                }
                //僵尸被减速逻辑
                if(reduce_statue)
                {
                    reduce_time-=update_fre;
                    walk_speed=walk_speed_reduce;
                    if(reduce_time<=0)
                        reduce_statue=false;
                }
                else
                {
                    walk_speed=walk_speed_normal;
                }

                int col=(x-330+40)/105;
                if(col>=0&&col<9&&plants[i][col]!=nullptr)
                {
                    if(eat_pre>=eat_fre)
                    {
                        eat_pre=0;
                        plants[i][col]->life-=attack;
                    }
                    else
                        eat_pre+=update_fre;
                }
                else
                {
                    x-=walk_speed;
                }
            }
        }
    }
}

void gameframework::ObservePlant(QPainter *pa, QPixmap &pm)
{
    for(int i=0;i<plants.size();i++)
    {
        for(int j=0;j<plants[i].size();j++)
        {
            if(plants[i][j]!=nullptr)
            {
                if(plants[i][j]->life<=0)
                {
                    delete plants[i][j];
                    plants[i][j]=nullptr;
                }
                else
                {
                    QString str;
                    QString name=plants[i][j]->name;
                    int& effect_pre=plants[i][j]->effect_pre;
                    int effect_time=plants[i][j]->effect_time;
                    int attack=plants[i][j]->attack;
                    int w=130,h=130;
                    int x=330+j*105-14;
                    int y=170+210*i+60;
                    if(name=="坚果")
                    {
                        str=":/assitant/nut.png";
                        float init_l=plants[i][j]->init_life+0.00;
                        float l=plants[i][j]->life+0.00;
                        float rate=l/init_l;
                        pa->drawLine(x+10,y,x+10+80*rate,y);
                        w-=30;
                    }
                    else if(name=="樱桃炸弹")
                    {
                        if(effect_pre>=effect_time)
                        {
                            delete plants[i][j];
                            plants[i][j]=nullptr;
                            //填充植物效果
                            for(int t=0;t<zoms.size();t++)
                            {
                                for(int g=0;g<zoms[t].size();g++)
                                {
                                    int& life=zoms[t][g].life;
                                    int xz=zoms[t][g].x;
                                    int yz=zoms[t][g].y;
                                    if(abs(x-xz+14)<=170&&abs(y-yz-60)<=210)
                                    {
                                        life-=attack;
                                    }
                                }
                            }
                            w+=400;
                            h+=400;
                            x-=200;
                            y-=200;
                            str=":/assitant/Boom.png";
                        }
                        else
                        {
                            str=":/assitant/0.png";
                            effect_pre+=update_fre;
                        }
                        
                    }
                    else if(name=="寒冰菇")
                    {
                        str=":/assitant/hanbingu.png";
                        if(effect_pre>=effect_time)
                        {
                            delete plants[i][j];
                            plants[i][j]=nullptr;
                            //填充植物效果
                            for(int i=0;i<zoms.size();i++)
                            {
                                for(int j=0;j<zoms[i].size();j++)
                                {
                                    zoms[i][j].freeze_statue=true;
                                    zoms[i][j].freeze_time=4000;
                                }
                            }
                        }
                        else
                        {
                            
                            effect_pre+=update_fre;
                        }
                    }
                    Paint(pa,pm,str,x,y,w,h);
                    
                }
            }
        }
    }
}

void gameframework::ObserveSunshine(QPainter *pa, QPixmap &pm)
{
    auto it=collect_sun.begin();
    while(it!=collect_sun.end())
    {
        int&x =(*it).x;
        int& y=(*it).y;
        int des_x=(*it).des_x;
        int des_y=(*it).des_y;
        int fly_speed_x=(*it).fly_speed_x;
        int fly_speed_y=(*it).fly_speed_y;
        if(abs(x-des_x)<=50&&abs(y-des_y)<=50)
        {

            sum_sunnum+=75;
            it=collect_sun.erase(it);
            label_sunnum->setText(QString::number(sum_sunnum));
        }
        else
        {
            x+=fly_speed_x;
            y+=fly_speed_y;
            ++it;
        }
        Paint(pa,pm,":/background/sun.png",x,y,100,100);

    }
}

void gameframework::paintEvent(QPaintEvent *pe)
{
    game_time+=update_fre;
    if(game_time>=15*1000)
    {
        stage=2;

    }
    else if(game_time>=30*1000)
    {
        stage=3;

    }
    if(game_time>=30*1000&&zom_fre>=1500)
    {
        zom_fre-=2;
        add_life+=5;
    }

    QPainter* pa=new QPainter(this);
    QPixmap pm;
    pa->setPen(QPen(Qt::red,8));
    InitElement();
    InitGraph(pa,pm);
    ObserveBullet(pa,pm);
    ObserveZom(pa,pm);
    ObservePlant(pa,pm);
    ObserveSunshine(pa,pm);
    MakeZom();
    MakeBullet();
    delete pa;
}

void gameframework::keyPressEvent(QKeyEvent *ke)
{
    if(ke->key()==Qt::Key_1)
    {
        if(shoot_level==1&&sum_sunnum>=200)
        {
            shoot_level++;
            sum_sunnum-=200;
            label_sunnum->setText(QString::number(sum_sunnum));
            label_shoot_update->setText("按1射手升级:"+QString::number(update_shoot2)+"阳光");
        }
        else if(shoot_level==2&&sum_sunnum>=400)
        {
            shoot_level++;
            sum_sunnum-=400;
            label_sunnum->setText(QString::number(sum_sunnum));
            label_shoot_update->setText("按1射手升级:Max");
        }

    }
    else if(ke->key()==Qt::Key_2)
    {
        if(bullet_level==1&&sum_sunnum>=175)
        {
            bullet_level++;
            bullet_type++;
            sum_sunnum-=175;
            label_sunnum->setText(QString::number(sum_sunnum));
            label_bullet_update->setText("按2子弹升级:"+QString::number(update_bullet2)+"阳光");
        }
        else if(bullet_level==2&&sum_sunnum>=350)
        {
            bullet_type++;
            bullet_level++;
            sum_sunnum-=350;
            label_sunnum->setText(QString::number(sum_sunnum));
            label_shoot_update->setText("按2子弹升级:Max");
        }
    }
    if(ke->key()==Qt::Key_A)
    {
        if(col-1>=0)
            col--;

    }
    else if(ke->key()==Qt::Key_D)
    {
        if(col+1<9)
            col++;
    }
    else if(ke->key()==Qt::Key_W)
    {
        if(row-1>=0)
            row--;
    }
    else if(ke->key()==Qt::Key_S)
    {
        if(row+1<5)
            row++;
    }
}
void gameframework::mousePressEvent(QMouseEvent *me)
{
    int x=me->x(),y=me->y();
    qDebug()<<me->x()<<" "<<me->y();
    if(select_plant==false&&me->button()==Qt::LeftButton&&me->x()>=600&&me->x()<=1200&&me->y()<130)
    {
        int type=(me->x()-600)/70;
        select_plant=true;
        select_plant_type=type;

        return;
    }
    if(select_plant&&x>=330&&x<1250&&y>170&&y<=1250)
    {

        select_plant=false;
        QString str;
        plant* p=new plant;
        if(select_plant_type==0&&sum_sunnum>=150)
        {
            str="樱桃炸弹";
            p->attack=9999;  p->life=9999;
            sum_sunnum-=150;
            label_sunnum->setText(QString::number(sum_sunnum));
        }
        else if(select_plant_type==1&&sum_sunnum>=75)
        {
            str="寒冰菇"; p->life=9999;
            sum_sunnum-=75;
            label_sunnum->setText(QString::number(sum_sunnum));
        }
        else if(select_plant_type==2&&sum_sunnum>=50)
        {

            str="坚果";p->init_life=p->life=4000;
            sum_sunnum-=50;
            label_sunnum->setText(QString::number(sum_sunnum));
        }
        p->name=str;

        int row=(y-170)/210;
        int col=(x-330)/105;
        plants[row][col]=p;
    }
}

